package com.sls.game.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.socket.ServerDisponseException;
import com.sls.core.util.ServerDateAndTime;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.assist.Helper;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsOrderLogDAO;
import com.sls.game.page.Pagination;
import com.sls.game.parser.sls.OrderStatusSendParse;
import com.sls.game.pojo.DownstreamUserInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.GoodsOrderLog;
import com.sls.game.pojo.SLSHttpInterfaceInfo;
import com.sls.game.querybean.GoodsOrderQuery;
import com.sls.game.service.GoodsOrderService;
import com.sls.game.socket.SuperService;
import com.sls.game.supply.deal.AccountNoDeal;

@Service("goodsOrderService")
public class GoodsOrderServiceImpl extends SuperService implements
		GoodsOrderService {
	private static Logger log = Logger.getLogger(GoodsOrderServiceImpl.class);
	@Resource(name = "goodsOrderDAO")
	private GoodsOrderDAO goodsOrderDAO;

	private GoodsOrderLogDAO goodsOrderLogDAO;

	private Gson gson;

	private DownstreamUserDAO downstreamUserDAO;

	public DownstreamUserDAO getDownstreamUserDAO() {
		return downstreamUserDAO;
	}

	@Resource(name = "downstreamUserDAO")
	public void setDownstreamUserDAO(DownstreamUserDAO downstreamUserDAO) {
		this.downstreamUserDAO = downstreamUserDAO;
	}

	public GoodsOrderServiceImpl() {
		gson = CommonUtil.gson();
	}

	public GoodsOrderLogDAO getGoodsOrderLogDAO() {
		return goodsOrderLogDAO;
	}

	@Resource(name = "goodsOrderLogDAO")
	public void setGoodsOrderLogDAO(GoodsOrderLogDAO goodsOrderLogDAO) {
		this.goodsOrderLogDAO = goodsOrderLogDAO;
	}

	@Override
	public String queryOrders(String body, Head head)
			throws ServerDisponseException {
		GoodsOrderQuery orderQuery = gson.fromJson(body, GoodsOrderQuery.class);
		this.validate(orderQuery);
		this.validatePageCondition(orderQuery);
		try {
			Pagination<GoodsOrderInfo> page = this.goodsOrderDAO
					.queryOrders(orderQuery);
			if (page != null) {
				return gson.toJson(page);
			}
		} catch (Exception e) {
			log.error(e.toString());
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		return null;
	}

	@Override
	public String queryOrderByOrderId(String body, Head head)
			throws ServerDisponseException {
		GoodsOrderInfo orderInfo = gson.fromJson(body, GoodsOrderInfo.class);
		this.validate(orderInfo);
		this.validateOrderId(orderInfo);
		try {
			orderInfo = this.goodsOrderDAO.queryByOrderId(orderInfo
					.getOrderId());
			if (orderInfo != null) {
				return gson.toJson(orderInfo);
			}
		} catch (Exception e) {
			log.error(e.toString());
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		return null;
	}

	@Override
	public String update(String body, Head head) throws ServerDisponseException {
		GoodsOrderInfo orderInfo = gson.fromJson(body, GoodsOrderInfo.class);
		this.validate(orderInfo);
		this.validateOrderId(orderInfo);
		if (StringUtils.isEmpty(orderInfo.getStatus())) {
			throw new ServerDisponseException(
					ExceptionCodeDes.ORDER_STATUS_NULL.getCode(),
					ExceptionCodeDes.ORDER_STATUS_NULL.getDescription());
		}

		String status = orderInfo.getStatus();
		if ("0".equals(status)) { // 失败
			orderInfo.setResult("ORDER_FAILED");
			orderInfo.setSynOrAsy("1");

		} else if ("1".equals(status)) { // 成功
			orderInfo.setResult("ORDER_SUCCESS");
			orderInfo.setSynOrAsy("1");

		} else if ("2".equals(status)) { // 处理中
			orderInfo.setResult("ORDER_UNDERWAY");

		} else if ("3".equals(status)) { // 存疑
			orderInfo.setResult("ORDER_DUBIOUS");
		} else if ("4".equals(status)) { // 冲销
			// ...
		}
		try {
			this.goodsOrderDAO.update(orderInfo);
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		// 订单日志表插记录
		try {
			String orderId = orderInfo.getOrderId();
			GoodsOrderInfo goodsOrderInfo1 = new GoodsOrderInfo();
			goodsOrderInfo1 = this.goodsOrderDAO.queryByOrderId(orderId);
			if (goodsOrderInfo1 != null) {
				GoodsOrderLog orderLog = Helper.copy(goodsOrderInfo1);
				orderLog.setId(UUID.randomUUID().toString());
				orderLog.setModifyTime(ServerDateAndTime
						.getNowDateTimeOfFormat());
				this.goodsOrderLogDAO.insert(orderLog);
			}

		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

		return null;
	}

	@Override
	public List<String> querySupplyNameList(Head head)
			throws ServerDisponseException {
		List<String> nameList = null;
		try {
			nameList = this.goodsOrderDAO.querySupplyNameList();
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		return nameList;
	}

	@Override
	public List<GoodsOrderInfo> queryOrderInfoBySupplyName(String body,
			Head head) throws ServerDisponseException {
		GoodsOrderInfo info = gson.fromJson(body, GoodsOrderInfo.class);
		this.validate(info);
		if (StringUtils.isEmpty(info.getSupplyName())) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SUPPLY_NAME_NULL.getCode(),
					ExceptionCodeDes.SUPPLY_NAME_NULL.getDescription());
		}
		try {
			List<GoodsOrderInfo> list = this.goodsOrderDAO
					.queryOrderInfoBySupplyName(info);
			if (list != null && !list.isEmpty()) {
				return list;
			}
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		return null;
	}

	/**
	 * 校验是否为null
	 * 
	 * @param obj
	 * @throws ServerDisponseException
	 */
	private void validate(Object obj) throws ServerDisponseException {
		if (obj == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.PARSE_REQUEST_ERROR.getCode(),
					ExceptionCodeDes.PARSE_REQUEST_ERROR.getDescription());
		}
	}

	/**
	 * 校验分页必传参数是否为空 m
	 * 
	 * @param orderQuery
	 */
	private void validatePageCondition(GoodsOrderQuery orderQuery) {
		String currentPage = String.valueOf(orderQuery.getCurrentPage());
		String pageSize = String.valueOf(orderQuery.getPageSize());
		if (StringUtils.isEmpty(currentPage)) {
			throw new ServerDisponseException(
					ExceptionCodeDes.CURRENT_PAGE_NULL.getCode(),
					ExceptionCodeDes.CURRENT_PAGE_NULL.getDescription());
		} else if (StringUtils.isEmpty(pageSize)) {
			throw new ServerDisponseException(
					ExceptionCodeDes.PAGE_SIZE_NULL.getCode(),
					ExceptionCodeDes.PAGE_SIZE_NULL.getDescription());
		} else {

		}
	}

	/**
	 * 校验订单编号是否为空
	 * 
	 * @param orderInfo
	 */
	private void validateOrderId(GoodsOrderInfo orderInfo) {
		if (StringUtils.isEmpty(orderInfo.getOrderId())) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SLS_ORDERID_NULL.getCode(),
					ExceptionCodeDes.SLS_ORDERID_NULL.getDescription());
		}
	}

	/**
	 * 手动订单最终结果异步通知
	 * 
	 * @param body
	 * @param head
	 * @return
	 * @throws ServerDisponseException
	 * @date 2013-01-30
	 * @author Wangxg
	 */
	@Override
	public String updateSendAsynMsg(String body, Head head)
			throws ServerDisponseException {
		if (log.isInfoEnabled()) {
			log.info("进入Service开始处理[" + head.getRequestId() + "]的请求");
		}
		// 对消息body进行解析
		GoodsOrderInfo orderInfo = gson.fromJson(body, GoodsOrderInfo.class);
		this.validate(orderInfo);
		String orderId = orderInfo.getOrderId();
		boolean flag = checkDataOfQuerySendAsynMsg(orderId);
		if (flag) {
			GoodsOrderInfo goodsOrderInfo = null;
			goodsOrderInfo = goodsOrderDAO.queryByOrderId(orderId);
			if (goodsOrderInfo != null) {
				sendAsynMsg(goodsOrderInfo, orderId);
			}
		}

		return null;
	}

	/**
	 * 手动异步通知下游订单结果
	 * 
	 * @param goodsOrderInfo
	 * @param orderId
	 * @author Wangxg
	 * @date 2013-02-01
	 */
	private void sendAsynMsg(GoodsOrderInfo goodsOrderInfo, String orderId) {
		// 下游用户编号
		String contractId = goodsOrderInfo.getContractId();
		String secretKey = null; // 下游用户密钥
		DownstreamUserInfo downstreamUserInfo = null;
		downstreamUserInfo = downstreamUserDAO.queryUserByUserNO(contractId);
		if (downstreamUserInfo != null) {
			secretKey = downstreamUserInfo.getSecretKey();
		}

		// 回调地址
		String notifyUrl = goodsOrderInfo.getNotifyUrl();
		// 合作方订单编号
		String ptOrderNo = goodsOrderInfo.getMerchantOrderId();
		// 手拉手订单编号
		String supOrderNo = orderId;
		// 订单处理结果
		String status = goodsOrderInfo.getStatus();
		if ("1".equals(status)) { // 成功
			status = "ORDER_SUCCESS";
		} else if ("0".equals(status)) { // 失败
			status = "ORDER_FAILED";
		}

		// 手拉手充值成功时间
		String supOrderSuccessTime = goodsOrderInfo.getSupOrderSuccessTime();
		// 下游回调失败次数
		String failureNum = goodsOrderInfo.getfailureNum();

		if (failureNum != null && !("".equals(failureNum))) {
			int failureNumVal = Integer.parseInt(failureNum);
			if (failureNumVal < 3) {
				sendHttpMsg(ptOrderNo, supOrderNo, status, supOrderSuccessTime,
						secretKey, notifyUrl, orderId, failureNum);
			} else { // ---------失败次数超过3次,不再主动通知下游结果
				dealAsynResResult(null, orderId, failureNum);
			}
		} else {
			sendHttpMsg(ptOrderNo, supOrderNo, status, supOrderSuccessTime,
					secretKey, notifyUrl, orderId, failureNum);
		}

	}

	/**
	 * 发送http消息
	 * 
	 * @param ptOrderNo
	 * @param supOrderNo
	 * @param status
	 * @param supOrderSuccessTime
	 * @param secretKey
	 * @param notifyUrl
	 * @param orderId
	 * @param failureNum
	 */
	private void sendHttpMsg(String ptOrderNo, String supOrderNo,
			String status, String supOrderSuccessTime, String secretKey,
			String notifyUrl, String orderId, String failureNum) {
		String para = createParameter(ptOrderNo, supOrderNo, status,
				supOrderSuccessTime, secretKey);
		String httpUrl = notifyUrl + "?" + para;
		HttpClient httpClient = new HttpClient();
		// 供应商返回消息编码方式
		String supplyEncode = "UTF-8";
		try {
			log.info("手动异步通知下游订单最终结果内容：" + "\n合作方订单编号：" + ptOrderNo
					+ "\n手拉手订单编号:" + supOrderNo + "\n订单处理结果:" + status
					+ "\n手拉手充值成功时间:" + supOrderSuccessTime);
			log.info("异步通知url：" + httpUrl);

			// 给下游发消息
			String xmlStr = httpClient.doGet(httpUrl, supplyEncode);
			log.info("手动异步通知下游订单最终结果返回内容：" + xmlStr);

			dealAsynResResult(xmlStr, orderId, failureNum);
		} catch (Exception e) {
			log.error(e);
		}
	}

	/**
	 * 更新异步通知状态
	 * 
	 * @param xmlStr
	 * @param orderId
	 * @param failureNum
	 */
	private void dealAsynResResult(String xmlStr, String orderId,
			String failureNum) {
		// 异步回调返回结果
		String handleResult = null;
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		if (xmlStr != null && !("".equals(xmlStr))) {
			SLSHttpInterfaceInfo slsInfo = null;
			slsInfo = OrderStatusSendParse.readUserSendMsg(xmlStr);
			if (slsInfo != null) {
				handleResult = slsInfo.getHandleResult();
			}

			if (!("SUCCESS".equals(handleResult))) { // 异步回调失败
				if (failureNum == null || "".equals(failureNum)) {
					failureNum = "0";
				}
				int failureNumVal = Integer.parseInt(failureNum) + 1;
				String failureNumStr = failureNumVal + "";
				goodsOrderInfo.setfailureNum(failureNumStr);
			} else {
				String failureNumStr = "0";
				goodsOrderInfo.setfailureNum(failureNumStr);
			}
		} else {
			handleResult = "SUCCESS";
		}

		goodsOrderInfo.setOrderId(orderId);
		goodsOrderInfo.setUserhandleResult(handleResult);

		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		// 写订单日志
		try {
			GoodsOrderInfo goodsOrderInfo1 = new GoodsOrderInfo();
			goodsOrderInfo1 = this.goodsOrderDAO.queryByOrderId(orderId);
			if (goodsOrderInfo1 != null) {
				GoodsOrderLog orderLog = Helper.copy(goodsOrderInfo1);
				orderLog.setId(UUID.randomUUID().toString());
				orderLog.setModifyTime(ServerDateAndTime
						.getNowDateTimeOfFormat());
				this.goodsOrderLogDAO.insert(orderLog);
			}

		} catch (Exception e) {
			log.error(e.toString());
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

	}

	/**
	 * 拼装异步通知参数
	 * 
	 * @param ptOrderNo
	 * @param supOrderNo
	 * @param status
	 * @param supOrderSuccessTime
	 * @return
	 */
	private String createParameter(String ptOrderNo, String supOrderNo,
			String status, String supOrderSuccessTime, String secretKey) {
		String para = null;
		String sign = createOfSign(ptOrderNo, supOrderNo, status,
				supOrderSuccessTime, secretKey);
		StringBuilder strBui = new StringBuilder();
		strBui.append("ptOrderNo=");
		strBui.append(ptOrderNo);
		strBui.append("&");
		strBui.append("supOrderNo=");
		strBui.append(supOrderNo);
		strBui.append("&");
		strBui.append("status=");
		strBui.append(status);

		if ("1".equals(status)) { // 成功
			strBui.append("&");
			strBui.append("supOrderSuccessTime=");
			strBui.append(supOrderSuccessTime);
		} else if ("0".equals(status)) { // 失败
			strBui.append("&");
			strBui.append("failedCode=");
			strBui.append("208");
		}
		strBui.append("&");
		strBui.append("sign=");
		strBui.append(sign);

		para = strBui.toString().trim();
		return para;
	}

	/**
	 * 生成签名字符串
	 */
	private String createOfSign(String ptOrderNo, String supOrderNo,
			String status, String supOrderSuccessTime, String secretKey) {
		StringBuilder strBui = new StringBuilder();
		strBui.append(ptOrderNo);
		strBui.append(supOrderNo);
		strBui.append(status);

		if ("1".equals(status)) { // 成功
			strBui.append(supOrderSuccessTime);
		} else if ("0".equals(status)) { // 失败
			strBui.append("208");
		}
		strBui.append(secretKey);

		String data = strBui.toString().trim();
		String sign = UtilMD5Encryption.createMD5Encryption(data);

		return sign;
	}

	/**
	 * 数据校验
	 */
	private boolean checkDataOfQuerySendAsynMsg(String orderId) {
		boolean flag = false;
		if (orderId == null || "".equals(orderId)) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SLS_ORDERID_NULL.getCode(),
					ExceptionCodeDes.SLS_ORDERID_NULL.getDescription());
		} else {
			flag = true;
		}

		return flag;
	}

	/**
	 * 查询所有上游账号
	 * 
	 * @param body
	 * @param head
	 * @return
	 * @throws ServerDisponseException
	 */
	@Override
	public String queryAccountNo(String body, Head head)
			throws ServerDisponseException {

		List<GoodsOrderInfo> list = new ArrayList<GoodsOrderInfo>();
		// 腾讯
		list = AccountNoDeal.getTencentAccount(list);
		// 沃谷
		list = AccountNoDeal.getWoguAccount(list);
		// 易百米
		list = AccountNoDeal.getEbaimiAccount(list);
		// 恩付
		list = AccountNoDeal.getEnfuAccount(list);
		// 捷易通
		list = AccountNoDeal.getJieyitongAccount(list);
		// 坚果网络
		list = AccountNoDeal.getNutsnetAccount(list);
		// 星启天
		list = AccountNoDeal.getXingqtAccount(list);
		// 云恩
		list = AccountNoDeal.getYunenAccount(list);

		/**
		 * 去订单表查询
		 */
		// GoodsOrderQuery orderQuery = gson.fromJson(body,
		// GoodsOrderQuery.class);
		// List<GoodsOrderQuery> accountList = null;
		// accountList = goodsOrderDAO.queryRegisterAccount(orderQuery);

		String resultBody = gson.toJson(list);
		return resultBody;
	}

	@Override
	public Long queryOrderTotalPrice(String body, Head head)
			throws ServerDisponseException {
		GoodsOrderQuery orderQuery = gson.fromJson(body, GoodsOrderQuery.class);
		this.validate(orderQuery);
		Long total = this.goodsOrderDAO.queryOrderTotalPrice(orderQuery);
		return total;
	}

	@Override
	public Long queryOrderCostTotalPrice(String body, Head head)
			throws ServerDisponseException {
		GoodsOrderQuery orderQuery = gson.fromJson(body, GoodsOrderQuery.class);
		this.validate(orderQuery);
		Long costTotal = this.goodsOrderDAO.queryOrderCostTotalPrice(orderQuery);
		return costTotal;
	}

	@Override
	public Long queryOrderTotalParvalue(String body, Head head)
			throws ServerDisponseException {
		GoodsOrderQuery orderQuery = gson.fromJson(body, GoodsOrderQuery.class);
		this.validate(orderQuery);
		Long parvalueTotal = this.goodsOrderDAO.queryOrderTotalParvalue(orderQuery);
		return parvalueTotal;
	}

	@Override
	public Long queryOrderTotalNum(String body, Head head)
			throws ServerDisponseException {
		GoodsOrderQuery orderQuery = gson.fromJson(body, GoodsOrderQuery.class);
		this.validate(orderQuery);
		Long numTotal = this.goodsOrderDAO.queryOrderTotalNum(orderQuery);
		return numTotal;
	}

}
